In this lecture, we're going to learn how to script a sliding UI bar to allow our players to independently
control the transparency of other players in the game, as shown here.
So each player in the game is able to control whether or not they'd like to see other players characters
when they are going through the Abbey.
So let's go ahead and get started.
We're going to create a new script or a module script inside of starter player scripts and our handler
section.
So we'll call this.
Our setting guy handler, and we're going to use that same template that we've used before.
We'll paste that in here.
I'm going to rename this to our setting guy handler.
Again you use control shift and R to rename a variable.
And inside of here we want to create some functions for updating transparency for players in our game.
For example, we want to have a function to update the transparency for a particular character.
So we would pass a character as well as the transparency to set for this character.
We would also like to have a function to update all of the transparency for players in our game.
So we could call this function update.
Transparency for all players.
And again, we would pass a transparency value here.
And this would go and loop through all of the players in our game, see if they have a character and
then use the update transparency for function on them.
And then we also want to make sure we listen to whenever a player's character is added to the game.
So if another player's, uh, character dies and then they respawn with a new character, we want to
make sure we update the transparency of all of the descendants in that character, equal to whatever
the current transparency our player has for their guy.
So we'll create a function to listen for when a character is added and that will get passed a character.
And then we also need a function to go ahead and calculate the current transparency based on the position
of the slider across this bar here.
So we'll call this function calculate and update transparency.
Now, to make this transparency slider work, we're going to need the run service.
We're also going to need the players service as well.
And then we're also going to need the user input service.
That way we can go ahead and listen for when the player releases their mouse button or stops input,
which notifies us to, uh, basically have this slider stop following the player's, uh, mouse.
So what we can go ahead and do is create a variable for our player.
We'll call it local player and that's equal to players dot local player.
We'll get the guy that we need to affect.
So inside of starter GUI we have a setting GUI.
So that's going to be equal to our local player.
Get their player GUI folder and we're going to wait for that guy to replicate.
And then we're also going to go ahead and grab that button that they can click to drag around the slider.
So we'll call that the transparency button.
And that's in the GUI dot main frame dot transparency slider.
And there's a button in there called text button.
Then we can have a buoyant to tell whether or not we're currently pressing down on that button.
So we'll call it currently.
Pressing button and we'll set that equal to false by default.
We'll also have a variable to keep track of the current transparency they have set, which is going
to be zero by default.
And then since we're going to be using the run service to constantly update the position of that slider,
um, we're going to be using some functions in there like Udim two and math dot clamp.
And it's actually faster if we store those functions in local variables on our machine instead of having
to index, uh, globals for those functions.
So we'll create two variables.
I'll call one of them new Udim two and the other one we're just going to call clamp.
And that's going to be equal to Udim two dot new as well as math dot clamp.
So we're basically copying these functions and storing them in local variables which makes them faster
to reference under the hood.
Now what we can go ahead and do in our initialize function is we can listen for when a player is added
to the game.
And we'll get that player.
And we want to listen for when that player has a character added.
And we connect the on character added function to that event.
And then we also want to loop through all of the existing players in our game.
So for every player and player's get, players we want to do is we want to make sure that this player
is not equal to our local player.
So if it is, we'll just continue looping to the next player.
Otherwise, we'll connect to the character added event with our on character added function.
And then inside of the start function is where we're going to be listening for all the input on our
UI.
So for example, with our transparency button, we want to listen for when that gets, uh, clicked
or the mouse gets pressed down on the button.
And that's where we would set currently pressing button equal to true.
And then from that point when we know that we have pressed down on that button, then we can connect
to like, uh, the run service to start updating the position of that slider when the player moves their
mouse around.
However, we also want to listen for when the player releases their mouse off of that button.
And the best way to do that would be to use the input service.
And then we want to listen for the mouse button one input.
Because sometimes, since we're going to be constraining the position of this button to be across our
slider, if the player drags their mouse away and then releases some times, um, it's not going to
be very consistent with firing that, uh, mouse button one up event for the button itself.
So we want to use the user input service to guarantee when the player releases their left mouse button
that we stop moving this slider.
So in the user input service we would listen to the input ended event.
And get that input as well as the game process.
Bouillon.
And then we would actually go ahead and set currently pressing button equal to false when we verify
that the input.
Is equal to mouse button one.
If the user input type is not equal to the enum dot user input.
Type dot mouse button one.
Then we'll just return.
Otherwise we'll know that we are not currently pressing the button once we release the mouse button,
right?
However, when we press down our mouse button, that means we want to connect to the run service.
Dot, we'll get the render step event.
So actually we'll bind to render step and we'll call this slider update.
And the priority is going to be enum dot render priority dot.
Um we'll run it after I don't know we'll do it after the character.
So we'll do character dot value plus one.
And then we'll pass our function, which is actually going to be we're going to use the calculate and
update transparency function for the run service.
So every single frame it's going to calculate the current transparency and update the position of our
slider based on where our mouse is in accordance with this slider.
And then when we release our mouse button then we can go ahead and unbind from the run service.
So we would copy this.
And unbind from render.
Stepped slider update.
Okay, cool.
So what we want to do is we want to go ahead and fill out our calculate and update transparency function.
Inside of here.
What we're going to do is we're first going to get the position of the player's mouse, and we're going
to use the user input service and use the get mouse location function to get the current vector two
of the mouse position on the screen.
Now we want to get the difference between our mouse's current position and the current absolute position
of our slider object here on our screen.
So I'm going to create a variable called difference.
And it's going to be equal to our mouse position.
And we're going to subtract this value by our GUI mainframe.
We're going to get the transparency slider and get its absolute position on the screen in pixels.
So now we have a difference between where our mouse position is at based on the transparency slider.
And from this value, we can go ahead and calculate what the current transparency is.
So when the players mouse moves over then we're going to have a positive value.
And then we can go ahead and calculate that using that difference to see how much that difference matches
the total length of the slider.
So for example if this sliders length is 100 pixels and let's say our mouse is at a halfway point,
which would indicate a difference of 50 pixels, well 50 is half of 100.
So our transparency would be 0.5.
So we can calculate the current transparency.
And we want to make sure we clamp that value between 0 and 1.
So we use the clamp function.
And what we're going to do is we're going to pass our difference here and get its value on the x axis,
because we don't care about the y axis.
Since this is a horizontal slider, and we're going to divide that value by the GUI dot main frame,
get the transparency slider.
And we want to get its absolute size on the x axis.
So now we're getting that uh value which is going to represent the transparency.
And we want to make sure we clamp that value between 0 and 1.
So now we have our new updated transparency that all of the players on our game should be.
And this is where we would like, uh, call our update transparency for all players function and pass
the current transparency at the same time.
We also want to make sure we update the position of that button on our screen to be equal to wherever
the mouse position is on the x axis.
So our transparency button, we want to set the position equal to a new Utum two.
And we're going to basically, uh, set its scale.
So that's going to be equal to whatever the current transparency we have is on the x axis, zero on
the offset.
And then for the Y scale we're just going to get the transparency button dot position dot y dot scale.
So we keep it the same and then zero on the offset.
So now the position of this slider is going to be equal to our current transparency.
So if our mouse moves to the halfway point well our current transparency is going to be 0.5.
And that means the position of this button is going to be set halfway in our slider.
And that means we're going to update all of the transparency for the players in our game.
So inside of this function, what we want to do is we want to loop through every single player inside
of players, get players.
And we want to do is we want to update the transparency for that particular player's character.
So we would pass player character here as well as the current transparency we want to set them to.
Now.
We want to make sure we don't update the transparency for our own character.
So if this player is equal to our local player, then we're just going to continue looping to the next
player.
Now inside of our update transparency for function.
What we're going to do is we're going to first verify that the player has a character, because this
might be nil right here.
So if there is no character then we're just going to return.
Otherwise we're going to loop through every single descendant inside of this character.
Get descendants.
And we want to make sure that this descendant is a base part.
So if this descendant is not a base part.
And we also want to account for any decals in the player's character for like t shirts.
So if this descendant is not a base part and this descendant.
Is not a decal, so not.
D cow.
Looks like I spelt descendants wrong.
So let me fix that descendant.
Then we're just going to continue looping.
Otherwise, what we can go ahead and do is we can go ahead and check to make sure that this descendant
is not the humanoid root part, because the humanoid root part always needs to be transparent.
So if the descendants name is equal to humanoid root part.
Then we can go ahead and just continue.
Or we can also check if you don't want to use the name, you can check if this descendant is equal to
character dot primary part, which would also be the root part.
Then we would continue looping.
Otherwise we're just going to set the transparency of this descendant equal to the transparency passed
to our function.
So now inside of the on character added event, when a new character is added or a new descendant is
added to this character, we want to make sure we update the transparency.
So when a new character is added, we're going to update the transparency for this character with this
new current transparency.
However, when a character is going to be added in our game, there's no guarantee that all of the descendants
in that character are going to be loaded or available to us.
So when we loop through all of the descendants, we might not have all of the descendants in the character.
So we want to listen to this character's descendant added event.
And we'll go ahead and get that descendant.
And basically just copy this stuff right here.
But instead of continue we're going to use the return keywords.
So if this descendant is the primary part or if it's not a base part or decal, we're going to ignore
it.
Otherwise we can go ahead and update the transparency of this descendant equal to, um, our current
transparency that we have.
Okay.
Perfect.
I think this is everything we need set up.
So we listen for when we press down our mouse button and we set this boolean equal to true or false.
And actually let's include this boolean inside calculate and update transparency.
So if we are not currently pressing our button then we're just going to return.
That way we can, you know, prevent any accidental executions of this function if we're not currently
pressing the button just in case.
So when we press down on our text button, we're going to bind to render step to start updating the
slider when the player moves it, and then when they release their mouse button, we know we're not
interacting with that button anymore, so we don't need to update the sliders position.
And as we update the sliders position, we're also going to be updating the transparency for all of
the players in our game.
And we're also going to be listening for when a player's characters are added.
And we're going to update the transparency to match whatever our current transparency is in the game.
So that was a lot of code to write without testing.
So let's actually go ahead and test to see if our slider is actually working in the first place.
So no errors in the console.
That's always great.
And if we click down on our slider, as you can see, it's falling along with the position of our mouse.
And since we're clamping the value of our transparency to be between 0 and 1, it's also clamping the
position of the slider to be between zero and one so it doesn't go beyond the size of our slider.
And then if I release my mouse button, as you can see, I'm no longer interacting with the slider if
I release it.
As you can see, we stop interacting with that slider.
So now we can set up a two player server and check to see if the transparency for other players are
being updated.
Okay, here I am in my two player server.
Let's go ahead and drag this slider.
And as you can see, my player disappears.
And then when I bring it back down, he slowly fades back in.
So now I have complete control over the transparency of other players in my game.
So if I'm playing this obby and I don't like to see other players or interact with other players, then
I can just completely fade them out.
However, we can still collide with them, which means we're going to have to update the collision group
of players in a future lecture to not collide with other players.
But as you can see, each client has independent control over the transparency of other players in the
game.
And even if I keep, let's say, the transparency at this value and I were to die and a new character
of mine were to be added into the game.
I'm still going to keep that transparency that this client has.
And then if I reset this character here, we should keep the player's character still invisible.
So as you can see, I still cannot see him, but I can interact with him because because we haven't
updated the collision group, we'll do that later.
But as you can see so far our slider for player transparency is working great.
That's all I have for you in this lecture, so I'll see you in the next one.